package cate.game.role.res.guild.boss;

import cate.common.util.TimeTool;
import cate.game.framework.ModuleMan;
import cate.game.role.Role;
import cate.game.role.res.guild.po.GuildPO;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@NoteClass("公会BOSS排行数据缓存管理")
public class GuildBossRankCacheManager extends ModuleMan {
    @NoteField("缓存的排行Map")
    private Map<String, GuildBossRankSPO> cachedRankMap;
    @NoteField("上次检测时间")
    private long lastCheckTime;

    @Override
    public void initDependent() throws Exception {
        if (cachedRankMap == null) {
            cachedRankMap = new ConcurrentHashMap<>();
        }
        lastCheckTime = System.currentTimeMillis();
    }

    /**
     * 循环检测
     */
    public void tick() {
        try {
            long nowTime = System.currentTimeMillis();
            // 不频繁的检测 1分钟1次差不多了
            if (nowTime - lastCheckTime < TimeTool.TimeCons.MINUTE) {
                return;
            }
            lastCheckTime = nowTime;
            cachedRankMap.entrySet().removeIf(entry -> entry.getValue().expiredTime <= nowTime);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 尝试获取玩家对应的公会排行信息
     *
     * @param role      玩家
     * @param combatNum BOSS序号
     */
    public EcResult<GuildBossRankPO> tryGetRoleRankPO(Role role, int combatNum) {
        EcResult<GuildBossRankPO> r = new EcResult<>();
        GuildPO guild = role.getRes().guild.getGuild();
        if (guild == null) {
            return r.fail(310450, "尚未加入公会");
        }
        if (combatNum == guild.boss.combatNumPass + 1 || (guild.boss.isLastCombat() && combatNum == guild.boss.combatNumPass)) {
            r.data = guild.boss.rank;
            return r.success();
        }
        GuildBossRankSPO spo = tryGetRankPO(GuildBossRankSPO.BUILD_KEY(guild.uid, combatNum));
        if (spo == null) {
            return r.fail("找不到对应记录");
        }
        r.data = spo.rankPO;
        return r.success();
    }

    /**
     * 尝试获取SPO
     *
     * @param key 键值
     */
    private GuildBossRankSPO tryGetRankPO(String key) {
        GuildBossRankSPO spo = cachedRankMap.get(key);
        if (spo != null) {
            return spo;
        }
        Optional<GuildBossRankSPO> op = game.facilities.getMongo().guildBossRank.findById(key);
        if (op.isPresent()) {
            spo = op.get();
            spo.expiredTime = System.currentTimeMillis() + TimeTool.TimeCons.MINUTE * 5;
            cachedRankMap.put(key, spo);
        }
        return op.orElse(null);
    }

    /**
     * 保存排行数据
     *
     * @param guildUid  公会UID
     * @param combatNum BOSS序号
     * @param temp      排行数据
     */
    public void saveRankPO(String guildUid, int combatNum, List<GuildBossRankItemPO> temp) {
        GuildBossRankSPO spo = new GuildBossRankSPO();
        spo._id = GuildBossRankSPO.BUILD_KEY(guildUid, combatNum);
        spo.guildUid = guildUid;
        spo.combatNum = combatNum;
        spo.rankPO = new GuildBossRankPO();
        spo.rankPO.list = new ArrayList<>(temp);
        spo.expiredTime = System.currentTimeMillis() + TimeTool.TimeCons.MINUTE * 5;
        cachedRankMap.put(spo._id, spo);
        game.facilities.getMongo().guildBossRank.save(spo);
    }
}
